package org.dromara.patrol.dubbo;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.google.common.collect.Lists;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.common.core.enums.patrol.snap.InspectStatus;
import org.dromara.common.core.exception.patrol.PatrolSnapFrameExtractionException;
import org.dromara.frame.api.RemoteFrameService;
import org.dromara.frame.api.domain.FrameImage;
import org.dromara.patrol.api.RemotePatrolSnapLogicService;
import org.dromara.patrol.api.domain.bo.RemotePatrolSnapBo;
import org.dromara.patrol.domain.PatrolSnapImg;
import org.dromara.patrol.service.IPatrolSnapImgService;
import org.dromara.patrol.service.IPatrolSnapPlanService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
@DubboService
public class RemotePatrolSnapLogicServiceImpl implements RemotePatrolSnapLogicService {

    @DubboReference(timeout = 10000)
    private RemoteFrameService remoteFrameService;

    private final IPatrolSnapImgService patrolSnapImgService;

    private final IPatrolSnapPlanService patrolSnapPlanService;

    @Override
    @GlobalTransactional
    public Boolean processBusinessLogic(RemotePatrolSnapBo remotePatrolSnapBo) {
        if (ObjUtil.isNull(remotePatrolSnapBo)
            || CollUtil.isEmpty(remotePatrolSnapBo.getDeviceIds())) {
            log.info("processBusinessLogic deviceIds is empty {}", remotePatrolSnapBo);
            return Boolean.TRUE;
        }
        try {
            // 调用rpc服务，通过设备id获取当前帧图片地址
            List<FrameImage> frameImages = remoteFrameService.extraction(remotePatrolSnapBo.getDeviceIds());
            if (CollUtil.isEmpty(frameImages)) {
                // 设备可能不在线，直接返回成功
                return true;
            }
            // 持久化图片数据
            if (patrolSnapImgService.insertBatch(getPatrolSnapImgList(remotePatrolSnapBo, frameImages))) {
                // 更新计划 snap_total、 latest_img_url 字段
                return patrolSnapPlanService.updateLatestImgUrlAndSnapTotalById(remotePatrolSnapBo.getPlanId(),
                    frameImages.get(0).getImgUrl(), frameImages.size());
            }
            throw new PatrolSnapFrameExtractionException("图片持久化失败");
        } catch (Exception e) {
            log.error("processBusinessLogic---->call---->remoteFrameService error", e);
            throw new PatrolSnapFrameExtractionException(e.getMessage());
        }
    }

    private List<PatrolSnapImg> getPatrolSnapImgList(RemotePatrolSnapBo remotePatrolSnapBo, List<FrameImage> frameImages) {
        if (CollUtil.isEmpty(frameImages)) {
            throw new PatrolSnapFrameExtractionException("get remoteFrameService result error: return empty list");
        }
        Map<Long, String> frameMap = frameImages.stream()
            .collect(Collectors
                .toMap(FrameImage::getDeviceId, FrameImage::getImgUrl));
        List<PatrolSnapImg> ret = Lists.newArrayListWithCapacity(remotePatrolSnapBo.getDeviceIds().size());
        Long planId = remotePatrolSnapBo.getPlanId();
        Long storeId = remotePatrolSnapBo.getStoreId();
        remotePatrolSnapBo.getDeviceIds().forEach(deviceId -> {
            PatrolSnapImg patrolSnapImg = new PatrolSnapImg();
            patrolSnapImg.setDeviceId(deviceId);
            patrolSnapImg.setStoreId(storeId);
            patrolSnapImg.setSnapPlanId(planId);
            patrolSnapImg.setImgUrl(frameMap.get(deviceId));
            patrolSnapImg.setInspectStatus(InspectStatus.NON_INSPECT.getCode());
            ret.add(patrolSnapImg);
        });
        return ret;
    }
}
